package cn.song.listener;

import cn.hutool.json.JSONUtil;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import cn.song.entity.easyexcel.ExcelModel;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;

/**
 * 解析监听器
 * <p>
 * 每解析一行会回调invoke()方法，
 * 整个excel解析结束会执行doAfterAllAnalysed()方法
 * <p>
 * AnalysisEventListener与ReadListener区别
 * 特征	AnalysisEventListener	ReadListener
 * 继承关系	继承自 ReadListener	最底层接口
 * 方法提供	提供 invokeHeadMap, invoke, doAfterAllAnalysed 等内置方法	只提供 invoke 和 doAfterAllAnalysed
 * 使用便利性	更加简便，减少编码工作量	需要手动实现所有逻辑
 * 适用场景	常规的 Excel 读取操作	高度定制化的需求，对性能要求高
 * 数据类型	通常与具体模型类一起使用	可以处理任意类型的数据
 * <p>
 * 总结
 * AnalysisEventListener: 如果你需要快速实现一个简单的 Excel 读取功能，并且希望利用 EasyExcel 提供的一些内置功能，推荐使用 AnalysisEventListener。
 * ReadListener: 如果你需要更高的灵活性和控制权，或者对性能有特殊要求，可以选择直接实现 ReadListener 接口。
 *
 * @author SongRenShuo
 * @date 2025/01/06
 */
@Slf4j
public class ExcelListener extends AnalysisEventListener<ExcelModel> {

    private final List<ExcelModel> dataList;

    public ExcelListener() {
        this.dataList = new ArrayList<>();
    }

    public ExcelListener(List<ExcelModel> dataList) {
        this.dataList = dataList;
    }

    /**
     * 每行解析处理回调
     *
     * @param object  一行数据
     * @param context 上下文
     */
    @Override
    public void invoke(ExcelModel object, AnalysisContext context) {
        log.info("当前行：{} 当前值：{}",context.readRowHolder().getRowIndex(),JSONUtil.toJsonStr(object));
        //根据自己业务做处理
        doSomething(object);
    }

    private void doSomething(ExcelModel object) {
        dataList.add(object);
    }

    /**
     * 全部解析完成处理
     *
     * @param context 上下文
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        log.info("全部处理完成");
    }
}
